Preparation

My plan for this assignment was to design a circuit that outputs Mario's theme music through a buzzer.

Circuit design

circuit

The circuit consists of the attiny44 microcontroller, a decoupling capacitor and a buzzer. The basic funtion of the circuit is that the microcontroller sends an array of signals that have different frequencies and delays. Note: The circuit consists of two unnecessary connections for this design: Tx and Rx connections between the female header and the microcontroller




Milling and soldering

pcb

The circuit was designed to have 14-20mil traces with a clearance of 15 mils. The blue outer rectangle is a wire that was placed on the bottom layer of the pcb, and used only for the cutout stage.
The first version of the circuit had a ratsnest for the ground, but there was an issue from with either fabmodules or eagle where some traces were not going to be milled properly, eventough the drill size was 1/64 inches. So, I avoided using a ratsnest for this design and connected the ground with normal traces.

Traces png file

traces

Cutout png file

cutout

Result after soldering

top1

bottom1





Programming

The frequency and delay of the tune was obtained from here

The code in the link above can be run on a Windows compiler such as GCC. There are only two functions that I am innterested in, which are: Beep(x,y) and Sleep(z).

The x parameter in the Beep function is the frequency in Hertz and the y parameter is the duration in which the beep can be heard in milliseconds.
The z parameter in the Sleep function specifies the time delay in milliseconds.

Programmer bash file

I have created a bash file that makes reprogramming the microcontoller easier. This bash file reprograms the microcontroller just by running "bash Program", where Program stands for the file name of the bash file. The code inside the file is shown below:
#!/bin/bash

avr-gcc -w -Os -DF_CPU=2000000UL -mmcu=attiny44 -c -o main.o main.c
avr-gcc -w -mmcu=attiny44 main.o -o main
avr-objcopy -O ihex -R .eeprom main main.hex
sudo avrdude -F -V -c usbtiny -p t44 -P usb -U flash:w:main.hex:i

Code

Here is how I have designed the code:
First of all, the windows library cannot be added to the microcontroller, so the Beep and Sleep functions will not work. So, for the Beep I have created a function that inputs in the frequency and outputs it as a 50% dutycycle square wave that has the inputted frequency. The following explains how the conversion equation was done:

Conversion

void interval(int x)
{
int beep = x;
int on = 1000000/(beep*2);
int t = 100000/(on*2)*2;
int i = 0;
for (i=0; i<t; i++){
PORTA |= 0b10001000;mydelay(on/8);
PORTA &= ~(0b10001000);mydelay(on/8);
}
}


int beep = x;
This is unnecessary and useless ^^

int on = 1000000/(beep*2);
Here I am calculating the on and off time of the wave (since the wave has 50% dutycycle)
First, I'm converting the frequency to time (f=1/t) and the dividing it by 2
So far im left with half of the period of the wave. To take as an example, the frequency of the beeps go up to ~1100Hz and if this was the input frequency to the function, the "on" time will be 0.000909 seconds. Since "on" is assigned as an integer, the number will be rounded down to 0. In order to solve this issue, Ive multiplied the time by 10^6 to convert it to micro seconds.

int t = 100000/(on*2)*2;
This is a bad name for a variable. Here t does not stand time, but it stands for the number of times the for loop would run in order to generate a beep for 100 milliseconds (since most of the beep durations are 100 milliseconds or a multiple of that). on was multipled by 2 in order to get the period. 1000/(on*2) will give you the number of loops for 1ms (since the unit of on is us) and multiplying it by 100 will give the number of loops for a 100ms beep. The reason why I doubled the time is explained later***

int i = 0;
self explanatory

for (i=0; i<t; i++){
same

PORTA |= 0b00001000;mydelay(on/8);
Here Im calling pin number 10 on the microcontroller to output for on microseconds. Through the datasheet, I have found that pin 10 is a porta pin and is labelled as PA3 as shown in the image below. 0b is the prefix for calling a pin in binary and PA3 is the 4th pin and 4 is translated as 1000 in binary (the other zeroes are for the rest of the porta pins (8 total)). mydelay is another function. The reason why I needed to add this function is that the compiler will not compile the delay unless a fixed variable is inputted. The reason why I divided the on time by 8 is explained later***

datasheet



PORTA &= ~(0b00001000);mydelay(on/8);
This is actually the off part of the signal

Calling the function

Sample of one beep:

int freq = 330;
Here I am specifying the frequency of the square wave.

interval(freq);_delay_ms(0.25*100);
The frequency is inputted to the function, and the delay is the time between each beep. The reason why I reduced the delay by 4 times is explained later***

***

The reason why i have changed the t, on and delay time was that, when I first ran the code without changing them, i have noticed that the frequency of the beeps were definitely too low and the song was not recognisable if the listener did not have in mind that this is the super mario's the song. So I manipulated the frequency and time of the beep until I was satisfied with the result.

The whole code

#include <avr/io.h>
#include <util/delay.h>


void mydelay(int asd){
  int i =0;
	for (;i<asd;i++)
	_delay_us(1);
}

void interval(int x)
	{
		int beep = x;
		int on = 1000000/(beep*2);
		int t = 100000/(on*2)*2;
		int i = 0;
		for (i=0; i<t; i++){
	  	PORTA |= 0b10001000;mydelay(on/8);
  		PORTA &= ~(0b10001000);mydelay(on/8);
			}
	}

int main (void)
{
	DDRA = 0b10001000;
	
	
 while(1)
 {
	int freq = 330;
	interval(freq);_delay_ms(0.25*100);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 392;
	interval(freq);_delay_ms(0.25*700);

	freq = 196;
	interval(freq);_delay_ms(0.25*700);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*300);

	freq = 164;
	interval(freq);_delay_ms(0.25*300);

	freq = 164;
	interval(freq);_delay_ms(0.25*300);

	freq = 164;
	interval(freq);_delay_ms(0.25*300);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 246;
	interval(freq);_delay_ms(0.25*300);

	freq = 233;
	interval(freq);

	freq = 233;
	interval(freq);

	freq = 220;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*150);

	freq = 330;
	interval(freq);_delay_ms(0.25*150);

	freq = 392;
	interval(freq);_delay_ms(0.25*150);

	freq = 440;
	interval(freq);_delay_ms(0.25*300);

	freq = 349;
	interval(freq);_delay_ms(0.25*100);

	freq = 392;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*100);

	freq = 247;
	interval(freq);_delay_ms(0.25*500);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*300);

	freq = 164;
	interval(freq);_delay_ms(0.25*300);

	freq = 164;
	interval(freq);_delay_ms(0.25*300);

	freq = 164;
	interval(freq);_delay_ms(0.25*300);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 246;
	interval(freq);_delay_ms(0.25*300);

	freq = 233;
	interval(freq);

	freq = 233;
	interval(freq);

	freq = 220;
	interval(freq);_delay_ms(0.25*300);

	freq = 196;
	interval(freq);_delay_ms(0.25*150);

	freq = 330;
	interval(freq);_delay_ms(0.25*150);

	freq = 392;
	interval(freq);_delay_ms(0.25*150);

	freq = 440;
	interval(freq);_delay_ms(0.25*300);

	freq = 349;
	interval(freq);_delay_ms(0.25*100);

	freq = 392;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*100);

	freq = 247;
	interval(freq);_delay_ms(0.25*900);

	freq = 392;
	interval(freq);_delay_ms(0.25*100);

	freq = 370;
	interval(freq);_delay_ms(0.25*100);

	freq = 349;
	interval(freq);_delay_ms(0.25*100);

	freq = 311;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 207;
	interval(freq);_delay_ms(0.25*100);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*500);

	freq = 392;
	interval(freq);_delay_ms(0.25*100);

	freq = 370;
	interval(freq);_delay_ms(0.25*100);

	freq = 349;
	interval(freq);_delay_ms(0.25*100);

	freq = 311;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 523;
	interval(freq);_delay_ms(0.25*300);

	freq = 523;
	interval(freq);_delay_ms(0.25*100);

	freq = 523;
	interval(freq);_delay_ms(0.25*1100);

	freq = 392;
	interval(freq);_delay_ms(0.25*100);

	freq = 370;
	interval(freq);_delay_ms(0.25*100);

	freq = 349;
	interval(freq);_delay_ms(0.25*100);

	freq = 311;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*300);

	freq = 207;
	interval(freq);_delay_ms(0.25*100);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 220;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*500);

	freq = 311;
	interval(freq);_delay_ms(0.25*300);

	freq = 311;
	interval(freq);_delay_ms(0.25*300);

	freq = 311;
	interval(freq);_delay_ms(0.25*300);

	freq = 296;
	interval(freq);_delay_ms(0.25*300);

	freq = 296;
	interval(freq);_delay_ms(0.25*300);

	freq = 296;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*1300);

	freq = 262;
	interval(freq);_delay_ms(0.25*1300);

	freq = 262;
	interval(freq);_delay_ms(0.25*1300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*50);

	freq = 330;
	interval(freq);_delay_ms(0.25*50);

	freq = 262;
	interval(freq);_delay_ms(0.25*50);

	freq = 262;
	interval(freq);_delay_ms(0.25*50);

	freq = 220;
	interval(freq);_delay_ms(0.25*50);

	freq = 220;
	interval(freq);_delay_ms(0.25*50);

	freq = 196;
	interval(freq);_delay_ms(0.25*700);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*100);

	freq = 330;
	interval(freq);_delay_ms(0.25*700);

	freq = 440;
	interval(freq);_delay_ms(0.25*300);

	freq = 392;
	interval(freq);_delay_ms(0.25*500);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*300);

	freq = 262;
	interval(freq);_delay_ms(0.25*100);

	freq = 294;
	interval(freq);_delay_ms(0.25*300);

	freq = 330;
	interval(freq);_delay_ms(0.25*50);

	freq = 330;
	interval(freq);_delay_ms(0.25*50);

	freq = 262;
	interval(freq);_delay_ms(0.25*50);

	freq = 262;
	interval(freq);_delay_ms(0.25*50);

	freq = 220;
	interval(freq);_delay_ms(0.25*50);

	freq = 220;
	interval(freq);_delay_ms(0.25*50);

	freq = 196;
	interval(freq);_delay_ms(0.25*700);
}
 return 0;
}


Download files:
Circuit schematic (eagle)
PCB(eagle)
Code


Result